/** * MTable - an extension of the JTable which binds to data in a ListValueHolder. * * Copyright (c) 2002 * Marty Phelan, All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ package com.taursys.swing; import javax.swing.table.*; import javax.swing.*; import javax.swing.JTable; import com.taursys.model.*; import javax.swing.event.*; import java.util.List; /** * MTable is an extension of the JTable which binds to data in a ListValueHolder. * When you create a new MTable, it creates all the required internal subcomponents * needed to be fully functional. You can change any of these subcomponents as * needed. Typically, you will create this MTable, set its listValueHolder * property, and indicate which properties to display by setting the columnNames * property. * <p> * There are two ways to setup the columns to display. The first is by simply * setting the columnNames property to a String array of property names. This * will use default formatting, widths and column titles. * Below is an example of this approach: * <pre> * private MTable holdersTable = new MTable(); * private VOListValueHolder holder = new VOListValueHolder(); * ... * private void jbInit() throws Exception { * holder.setValueObjectClass(com.taursys.tools.ValueHolderInfo.class); * holdersTable.setListValueHolder(holder); * holdersTable.setColumnNames(new String[] { * "holderName","holderAlias",}); * ... * </pre> * The second method gives you much more control over presentation. In this * approach, you create an <code>MTableColumn</code> for each column and set * its properties. You then add this column to the <code>MTable</code> using * the <code>addColumn</code> method. Below is an example of this approach: * <pre> * private MTable holdersTable = new MTable(); * private VOListValueHolder holder = new VOListValueHolder(); * private MTableColumn holderNameColumn = new MTableColumn(); * private MTableColumn holderAliasColumn = new MTableColumn(); * ... * private void jbInit() throws Exception { * holder.setValueObjectClass(com.taursys.tools.ValueHolderInfo.class); * holdersTable.setListValueHolder(holder); * holderNameColumn.setPreferredWidth(80); * holderNameColumn.setDisplayHeading("Name"); * holderNameColumn.setPropertyName("holderName"); * holderNameColumn.setValueHolder(holder); * holderNameColumn.setHeaderValue("Holder Name"); * holdersTable.addColumn(holderNameColumn); * holderAliasColumn.setDisplayHeading("Alias"); * holderAliasColumn.setPropertyName("holderAlias"); * holdersTable.addColumn(holderAliasColumn); * ... * </pre> * The MTable will display the 2 listed properties for every object in the * holder. You can add or remove any object from the holder and the changes * will be displayed in the table. Further, if the class which is contained * in the VOListValueHolder implements the BoundValueObject interface, any * changes to the values will be immediately displayed in the table. * <p> * The MTable uses a MTableModel which extends the of the AbstractTableModel. * The MTableModel uses a ListValueHolder to contain the actual data for this * table. The MTableModel uses a ListSelectionBinder to synchronize the * position in this table and the ListValueHolder. * @author Marty Phelan * @version 1.0 */ public class MTable extends JTable { /** * Construct a new MTable. */ public MTable() { setAutoCreateColumnsFromModel(true); getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); } /** * Create a TableModel to be used by this MTable. By default, this method * returns a MTableModel. It also sets the MTableModel's listSelectionModel * to this MTable's listSelectionModel. * @return a TableModel to be used by this MTable. */ protected TableModel createDefaultDataModel() { MTableModel m = new MTableModel(); m.setListSelectionModel(getSelectionModel()); return m; } /** * Set the class of the value object. Only needed if the valueObject * itself can be null. If set, this takes presidence over the actual * class of the valueObject. This property is only effective if the internal * ListValueHolder is an instanceof VOListValueHolder (which is the default). */ public void setValueObjectClass(Class newValueObjectClass) { if (getModel() != null && getModel() instanceof MTableModel) { getMTableModel().setValueObjectClass(newValueObjectClass); } } /** * Get the class of the value object. Only needed if the valueObject * itself can be null. If set, this takes presidence over the actual * class of the valueObject. This property is only effective if the internal * ListValueHolder is an instanceof VOListValueHolder (which is the default). */ public Class getValueObjectClass() { if (getModel() != null && getModel() instanceof MTableModel) { return getMTableModel().getValueObjectClass(); } else { return null; } } /** * Set the List that the internal ListValueHolder will use. This property is * only effective if the internal ListValueHolder is an instanceof * VOListValueHolder (which is the default). */ public void setList(List newList) { if (getModel() != null && getModel() instanceof MTableModel) { getMTableModel().setList(newList); } } /** * Gets the List that the internal ListValueHolder will use. This property is * only effective if the internal ListValueHolder is an instanceof * VOListValueHolder (which is the default). */ public List getList() { if (getModel() != null && getModel() instanceof MTableModel) { return getMTableModel().getList(); } else { return null; } } /** * Get the current MTableModel for this MTable. * @return the current MTableModel for this MTable. * @throws ClassCastException if the internal model does not subclass MTableModel. */ protected MTableModel getMTableModel() { return (MTableModel)getModel(); } /** * Get the ListValueHolder used by the MTableModel * @return the ListValueHolder used by the MTableModel */ public ListValueHolder getListValueHolder() { return getMTableModel().getListValueHolder(); } /** * Set the ListValueHolder used by the MTableModel. * This method also binds the * @param newListValueHolder the ListValueHolder used by the MTableModel */ public void setListValueHolder(ListValueHolder newListValueHolder) { getMTableModel().setListValueHolder(newListValueHolder); } /** * Set which columnNames (property names) to display in this MTable. * @param newColumnNames a String array of which columnNames (property names) to display in this MTable. */ public void setColumnNames(String[] newColumnNames) { getMTableModel().setColumnNames(newColumnNames); } /** * Get which columnNames (property names) to display in this MTable. * @return a String array of which columnNames (property names) to display in this MTable. */ public String[] getColumnNames() { return getMTableModel().getColumnNames(); } /** * Add column to ColumnModel for this table (and possibly to MTableModel). * If the given column is a MTableColumn, additional operations are performed. * It will try to set the modelIndex of the MTableColumn based on the * MTableColumn's propertyName property. If the propertyName is null or * blank, no action will occur. It will attempt to determine the modelIndex * by looking up the propertyName in the MTableModel. If not found, it will add * the propertyName to the MTableModel. It will then set the MTableColumn's * modelIndex to the index in the MTableModel. It will also set the * MTableColumn's valueHolder to the MTableModel's valueHolder. */ public void addColumn(TableColumn newColumn) { if (newColumn != null && newColumn instanceof MTableColumn) { MTableColumn col = (MTableColumn)newColumn; String propName = col.getPropertyName(); if (propName != null && propName.length() > 0) { int index = getMTableModel().findColumn(propName); if (index == -1) { getMTableModel().addColumn(propName); index = getMTableModel().findColumn(propName); } col.setModelIndex(index); col.setValueHolder(getMTableModel().getListValueHolder()); super.addColumn(newColumn); } else { com.taursys.debug.Debug.error("Attempt to add a MTableColumn without a propertyName"); } } else { super.addColumn(newColumn); } } }